//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V1.0.0
#include "uart_bsp.h"
#include <stdio.h>
#include <string.h>

/*串口总管理结构体*/
typedef struct
{
    WHT_UART_enum Name;     //串口号
    WHT_UART_Info_t Info;   //提供给外部
    WHT_UART_Cache_t* Cache;//外设缓存,由外部提供

    ControlStatus Dma_Receive;        //串口DMA功能
    WHT_DMA_Config_t DMA_Send_Config;   //DMA配置
    WHT_DMA_Config_t DMA_Receive_Config;//DMA配置
}WHT_Data_t;


static WHT_Data_t WHT_UART1;
static WHT_Data_t WHT_UART2;
static WHT_Data_t WHT_UART3;
static WHT_Data_t WHT_UART4;
static WHT_Data_t WHT_UART5;
static WHT_Data_t WHT_UART6;
static WHT_Data_t WHT_UART7;
static WHT_Data_t WHT_UART8;

#define WHT_UART     ((WHT_Data_t*)cache->Private_Data)//简化操作


/*串口GPIO初始化*/
static void WHT_UART_BSP_GPIO_Init(const WHT_UART_Config_t *config)
{
    switch (config->Name)
    {
    case UART_1:
        WHT_GPIO_BSP.WHT_Set_Clock(PortA, ENABLE);
        WHT_GPIO_BSP.WHT_Set_Pin(PortA, Pin9 | Pin10, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortA, Pin9 | Pin10, Mode_AF_PP);
		WHT_GPIO_BSP.WHT_Set_AFIO(PortA, Pin9, AFIO_USART0);
		WHT_GPIO_BSP.WHT_Set_AFIO(PortA, Pin10, AFIO_USART0);
        break;
    case UART_2:
        WHT_GPIO_BSP.WHT_Set_Clock(PortA, ENABLE);
        WHT_GPIO_BSP.WHT_Set_Pin(PortA, Pin2 | Pin3, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortA, Pin2 | Pin3, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortA, Pin2, AFIO_USART1);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortA, Pin3, AFIO_USART1);
        break;
    case UART_3:
        WHT_GPIO_BSP.WHT_Set_Clock(PortB, ENABLE);
        WHT_GPIO_BSP.WHT_Set_Pin(PortB, Pin10 | Pin11, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortB, Pin10 | Pin11, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortB, Pin10, AFIO_USART2);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortB, Pin11, AFIO_USART2);
        break;
    case UART_4:
        WHT_GPIO_BSP.WHT_Set_Clock(PortC, ENABLE);
        WHT_GPIO_BSP.WHT_Set_Pin(PortC, Pin10 | Pin11, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortC, Pin10 | Pin11, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortC, Pin10, AFIO_UART4);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortC, Pin11, AFIO_UART4);
        break;
    case UART_5:
        WHT_GPIO_BSP.WHT_Set_Clock(PortC, ENABLE);
        WHT_GPIO_BSP.WHT_Set_Clock(PortD, ENABLE);
        WHT_GPIO_BSP.WHT_Set_Pin(PortC, Pin12, Hig);
        WHT_GPIO_BSP.WHT_Set_Pin(PortD, Pin2, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortC, Pin12, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_Mode(PortD, Pin2, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortC, Pin12, AFIO_UART4);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortD, Pin2, AFIO_UART4);
        break;
    case UART_6:
        WHT_GPIO_BSP.WHT_Set_Clock(PortC, ENABLE);
        WHT_GPIO_BSP.WHT_Set_Pin(PortC, Pin6 | Pin7, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortC, Pin6 | Pin7, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortC, Pin6, AFIO_USART5);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortC, Pin7, AFIO_USART5);
        break;
    case UART_7:
        WHT_GPIO_BSP.WHT_Set_Clock(PortF, ENABLE);
        WHT_GPIO_BSP.WHT_Set_Pin(PortF, Pin6 | Pin7, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortF, Pin6 | Pin7, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortF, Pin6, AFIO_UART6);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortF, Pin7, AFIO_UART6);
        break;
    case UART_8:
        WHT_GPIO_BSP.WHT_Set_Clock(PortE, ENABLE);
        WHT_GPIO_BSP.WHT_Set_Pin(PortE, Pin0 | Pin1, Hig);
        WHT_GPIO_BSP.WHT_Set_Mode(PortE, Pin0 | Pin1, Mode_AF_PP);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortE, Pin0, AFIO_UART7);
        WHT_GPIO_BSP.WHT_Set_AFIO(PortE, Pin1, AFIO_UART7);
        break;
    default:
        break;
    }
}
/*串口中断优先级配置*/
static void WHT_UART_BSP_NVIC_Configuration(const WHT_UART_Config_t *config)
{
    IRQn_Type IRQn;

    /* 配置中断源 */
    switch (config->Name)
    {
    case UART_1:IRQn = USART0_IRQn; break;
    case UART_2:IRQn = USART1_IRQn; break;
    case UART_3:IRQn = USART2_IRQn; break;
#if defined(GD32F450) || defined(GD32F470)
    case UART_4:IRQn = UART3_IRQn;  break;
    case UART_5:IRQn = UART4_IRQn;  break;
    case UART_6:IRQn = USART5_IRQn; break;
    case UART_7:IRQn = UART6_IRQn;  break;
    case UART_8:IRQn = UART7_IRQn;  break;
#endif /* GD32F450 || GD32F470 */

#if defined(GD32F405) || defined(GD32F425)
    case UART_4:IRQn = UART3_IRQn;  break;
    case UART_5:IRQn = UART4_IRQn;  break;
    case UART_6:IRQn = USART5_IRQn; break; 
#endif /* GD32F405 || GD32F425 */

#if defined(GD32F407) || defined(GD32F427)
    case UART_4:IRQn = UART3_IRQn;  break;
    case UART_5:IRQn = UART4_IRQn;  break;
    case UART_6:IRQn = USART5_IRQn; break;                      
#endif /* GD32F407 || GD32F427 */
    default:
        return;
    }

    NVIC_SetPriority(IRQn, config->PreemptionPriority);
    NVIC_EnableIRQ(IRQn);
}
/*串口注册*/
static ErrStatus WHT_UART_BSP_Register(const WHT_UART_Config_t* config, const WHT_UART_Cache_t* cache)
{
    if ((WHT_UART != NULL) && (cache->Info != NULL))
        return SUCCESS;
    
    switch (config->Name)
    {
    case UART_1:rcu_periph_clock_enable(RCU_USART0); ((WHT_UART_Cache_t*)cache)->Private_Data = &WHT_UART1; break;
    case UART_2:rcu_periph_clock_enable(RCU_USART1); ((WHT_UART_Cache_t*)cache)->Private_Data = &WHT_UART2; break;
    case UART_3:rcu_periph_clock_enable(RCU_USART2); ((WHT_UART_Cache_t*)cache)->Private_Data = &WHT_UART3; break;
    case UART_4:rcu_periph_clock_enable(RCU_UART3);  ((WHT_UART_Cache_t*)cache)->Private_Data = &WHT_UART4; break;
    case UART_5:rcu_periph_clock_enable(RCU_UART4);  ((WHT_UART_Cache_t*)cache)->Private_Data = &WHT_UART5; break;
    case UART_6:rcu_periph_clock_enable(RCU_USART5); ((WHT_UART_Cache_t*)cache)->Private_Data = &WHT_UART6; break;
    case UART_7:rcu_periph_clock_enable(RCU_UART6);  ((WHT_UART_Cache_t*)cache)->Private_Data = &WHT_UART7; break;
    case UART_8:rcu_periph_clock_enable(RCU_UART7);  ((WHT_UART_Cache_t*)cache)->Private_Data = &WHT_UART8; break;
    default: return ERROR;
    }

    WHT_UART->Name = config->Name;
    ((WHT_UART_Cache_t*)cache)->Info = &WHT_UART->Info;
    WHT_UART->DMA_Send_Config.IT_Callback = NULL;
    WHT_UART->DMA_Receive_Config.IT_Callback = NULL;

    /*串口中断优先级配置*/
    WHT_UART_BSP_NVIC_Configuration(config);

    //将串口注册到DMA上
    switch (config->Name)
    {
    case UART_1:
        WHT_UART->DMA_Send_Config.Periph = Periph_USART1_TX;
        WHT_UART->DMA_Send_Config.Stream = Stream_USART1_TX;
        WHT_UART->DMA_Send_Config.Channel = Channel_USART1_TX;
        WHT_UART->DMA_Receive_Config.Periph = Periph_USART1_RX_1;
        WHT_UART->DMA_Receive_Config.Stream = Stream_USART1_RX_1;
        WHT_UART->DMA_Receive_Config.Channel = Channel_USART1_RX_1;
        break;
    case UART_2:
        WHT_UART->DMA_Send_Config.Periph = Periph_USART2_TX;
        WHT_UART->DMA_Send_Config.Stream = Stream_USART2_TX;
        WHT_UART->DMA_Send_Config.Channel = Channel_USART2_TX;
        WHT_UART->DMA_Receive_Config.Periph = Periph_USART2_RX;
        WHT_UART->DMA_Receive_Config.Stream = Stream_USART2_RX;
        WHT_UART->DMA_Receive_Config.Channel = Channel_USART2_RX;
        break;
    case UART_3:
        WHT_UART->DMA_Send_Config.Periph = Periph_USART3_TX_1;
        WHT_UART->DMA_Send_Config.Stream = Stream_USART3_TX_1;
        WHT_UART->DMA_Send_Config.Channel = Channel_USART3_TX_1;
        WHT_UART->DMA_Receive_Config.Periph = Periph_USART3_RX;
        WHT_UART->DMA_Receive_Config.Stream = Stream_USART3_RX;
        WHT_UART->DMA_Receive_Config.Channel = Channel_USART3_RX;
        break;
    case UART_4:
        WHT_UART->DMA_Send_Config.Periph = Periph_UART4_TX;
        WHT_UART->DMA_Send_Config.Stream = Stream_UART4_TX;
        WHT_UART->DMA_Send_Config.Channel = Channel_UART4_TX;
        WHT_UART->DMA_Receive_Config.Periph = Periph_UART4_RX;
        WHT_UART->DMA_Receive_Config.Stream = Stream_UART4_RX;
        WHT_UART->DMA_Receive_Config.Channel = Channel_UART4_RX;
        break;
    case UART_5:
        WHT_UART->DMA_Send_Config.Periph = Periph_UART5_TX;
        WHT_UART->DMA_Send_Config.Stream = Stream_UART5_TX;
        WHT_UART->DMA_Send_Config.Channel = Channel_UART5_TX;
        WHT_UART->DMA_Receive_Config.Periph = Periph_UART5_RX;
        WHT_UART->DMA_Receive_Config.Stream = Stream_UART5_RX;
        WHT_UART->DMA_Receive_Config.Channel = Channel_UART5_RX;
        break;
    case UART_6:
        WHT_UART->DMA_Send_Config.Periph = Periph_USART6_TX_1;
        WHT_UART->DMA_Send_Config.Stream = Stream_USART6_TX_1;
        WHT_UART->DMA_Send_Config.Channel = Channel_USART6_TX_1;
        WHT_UART->DMA_Receive_Config.Periph = Periph_USART6_RX_1;
        WHT_UART->DMA_Receive_Config.Stream = Stream_USART6_RX_1;
        WHT_UART->DMA_Receive_Config.Channel = Channel_USART6_RX_1;
        break;
    case UART_7:
        WHT_UART->DMA_Send_Config.Periph = Periph_UART7_TX;
        WHT_UART->DMA_Send_Config.Stream = Stream_UART7_TX;
        WHT_UART->DMA_Send_Config.Channel = Channel_UART7_TX;
        WHT_UART->DMA_Receive_Config.Periph = Periph_UART7_RX;
        WHT_UART->DMA_Receive_Config.Stream = Stream_UART7_RX;
        WHT_UART->DMA_Receive_Config.Channel = Channel_UART7_RX;
        break;
    case UART_8:
        WHT_UART->DMA_Send_Config.Periph = Periph_UART8_TX;
        WHT_UART->DMA_Send_Config.Stream = Stream_UART8_TX;
        WHT_UART->DMA_Send_Config.Channel = Channel_UART8_TX;
        WHT_UART->DMA_Receive_Config.Periph = Periph_UART8_RX;
        WHT_UART->DMA_Receive_Config.Stream = Stream_UART8_RX;
        WHT_UART->DMA_Receive_Config.Channel = Channel_UART8_RX;
        break;
    }
    WHT_DMA_BSP.WHT_Register(&WHT_UART->DMA_Send_Config);
    WHT_DMA_BSP.WHT_Register(&WHT_UART->DMA_Receive_Config);
    return SUCCESS;
}
/*串口配置*/
static void WHT_UART_BSP_Config(const WHT_UART_Config_t* config, const WHT_UART_Cache_t* cache)
{
    if ((WHT_UART == NULL) || (cache->Info == NULL))
        return;

    WHT_UART->Cache = (WHT_UART_Cache_t*)cache;

    /*临时关闭串口*/
    usart_disable(WHT_UART->Name);
    /*串口相关GPIO初始化*/
    WHT_UART_BSP_GPIO_Init(config);

    /* 串口波特率 */
    usart_baudrate_set(WHT_UART->Name, config->Bps);
    /* 校验位个数 */
    usart_parity_config(WHT_UART->Name, config->Parity);
    /* 数据长度 */
    usart_word_length_set(WHT_UART->Name, USART_WL_8BIT);
    /* 停止位个数 */
    usart_stop_bit_set(WHT_UART->Name, config->StopBits << 12);
    // 配置为无硬件流控制
    usart_hardware_flow_rts_config(WHT_UART->Name, USART_RTS_DISABLE);
    usart_hardware_flow_cts_config(WHT_UART->Name, USART_CTS_DISABLE);
    /* 发送和接收 */
    usart_receive_config(WHT_UART->Name, USART_RECEIVE_ENABLE);
    usart_transmit_config(WHT_UART->Name, USART_TRANSMIT_ENABLE);

    usart_interrupt_disable(WHT_UART->Name, USART_INT_RBNE);//关闭中断串口接收
    usart_interrupt_disable(WHT_UART->Name, USART_INT_IDLE);//关闭中断串口空闲
    usart_interrupt_disable(WHT_UART->Name, USART_INT_TBE); //关闭发送寄存器为空进入中断
    usart_interrupt_disable(WHT_UART->Name, USART_INT_TC);  //关闭数据发送完成且发送寄存器为空进入中断

    /*使能串口*/
    usart_enable(WHT_UART->Name);
}


/*串口阻塞发送*/
static void WHT_UART_BSP_Send(const WHT_UART_Cache_t* cache)
{
    WHT_UART->Info.Tx_State = UART_Tx_Busy;
    usart_dma_transmit_config(WHT_UART->Name, USART_TRANSMIT_DMA_DISABLE);//关闭串口发送DMA请求
    usart_interrupt_disable(WHT_UART->Name, USART_INT_TBE);
    usart_interrupt_disable(WHT_UART->Name, USART_INT_TC);
    usart_flag_clear(WHT_UART->Name, USART_FLAG_TC);//清除上次发送完成状态
    for (unsigned int tx_count = 0; tx_count < WHT_UART->Cache->Tx_Count; tx_count++)
    {
        usart_data_transmit(WHT_UART->Name, WHT_UART->Cache->Tx_Buf[tx_count]);
        while (!usart_flag_get(WHT_UART->Name, USART_FLAG_TBE));//等待发送寄存器为空
    }
    while (!usart_flag_get(WHT_UART->Name, USART_FLAG_TC));     //等待发送完成且发送寄存器为空
    WHT_UART->Info.Tx_State = UART_Tx_Idle;
}
/*串口中断发送*/
static void WHT_UART_BSP_Interrupt_Send(const WHT_UART_Cache_t* cache)
{
    WHT_UART->Info.Tx_State = UART_Tx_Busy;
    usart_dma_transmit_config(WHT_UART->Name, USART_TRANSMIT_DMA_DISABLE);//关闭串口发送DMA请求
    /*默认寄存器TC=1,TXE=1*/
    usart_interrupt_enable(WHT_UART->Name, USART_INT_TBE); //使能发送寄存器为空进入中断
    usart_interrupt_enable(WHT_UART->Name, USART_INT_TC);  //使能数据发送完成且发送寄存器为空进入中断
}
/*串口DMA发送*/
static void WHT_UART_BSP_DMA_Send(const WHT_UART_Cache_t* cache)
{
    dma_single_data_parameter_struct DMA_InitStruct =
    {
        .periph_addr            = (unsigned int)0,            //外设地址
        .memory0_addr           = (unsigned int)0,            //存储器地址
        .direction              = DMA_MEMORY_TO_PERIPH,       //M->P
        .number                 = 0,                          //传输个数
        .circular_mode          = DMA_CIRCULAR_MODE_DISABLE,  //单次模式
        .periph_inc             = DMA_PERIPH_INCREASE_DISABLE,//外设地址不递增
        .memory_inc             = DMA_MEMORY_INCREASE_ENABLE, //存储器地址递增
        .periph_memory_width    = DMA_PERIPH_WIDTH_8BIT,      //外设数据大小为字节
        .priority               = DMA_PRIORITY_LOW,           //优先级最低
    };

    WHT_UART->Info.Tx_State = UART_Tx_Busy;//发送置为忙碌
  
    DMA_InitStruct.periph_addr = WHT_UART->Name + 0x04U;                //外设基地址
    DMA_InitStruct.memory0_addr = (unsigned int)WHT_UART->Cache->Tx_Buf;//存储器地址
    DMA_InitStruct.number = WHT_UART->Cache->Tx_Count;                  //传输数据个数
    WHT_UART->DMA_Send_Config.DMA_InitStruct = &DMA_InitStruct;

    usart_interrupt_disable(WHT_UART->Name, USART_INT_TBE);//发送寄存器为空
    usart_interrupt_disable(WHT_UART->Name, USART_INT_TC); //数据发送完成且发送寄存器为空

    while (WHT_UART->DMA_Send_Config.Info->BSP_Mutex == SET);//等待没有外设使用此通道的DMA
    WHT_UART->DMA_Send_Config.Info->BSP_Mutex = SET;         //DMA通道上锁
    WHT_DMA_BSP.WHT_Config(&WHT_UART->DMA_Send_Config);      //配置当前DMA

    usart_flag_clear(WHT_UART->Name, USART_FLAG_TC);
    usart_dma_transmit_config(WHT_UART->Name, USART_TRANSMIT_DMA_ENABLE);//使能串口DMA发送请求
    usart_interrupt_enable(WHT_UART->Name, USART_INT_TC); //数据发送完成且发送寄存器为空
}

/*串口中断接收*/
static void WHT_UART_BSP_Interrupt_Receive(const WHT_UART_Cache_t* cache)
{
    usart_dma_receive_config(WHT_UART->Name, USART_RECEIVE_DMA_DISABLE);//关闭串口DMA接收请求

    WHT_UART->Info.Rx_State = UART_Rx_Idle;
    WHT_UART->Cache->Rx_Count = 0;
    WHT_UART->Dma_Receive = DISABLE;

    usart_interrupt_enable(WHT_UART->Name, USART_INT_RBNE);//接收寄存器非空
    usart_interrupt_enable(WHT_UART->Name, USART_INT_IDLE);//数据接收完成且总线空闲
    usart_receive_config(WHT_UART->Name, USART_RECEIVE_ENABLE);//开启串口接收
}
/*串口DMA接收*/
static void WHT_UART_BSP_DMA_Receive(const WHT_UART_Cache_t* cache)
{
    dma_single_data_parameter_struct DMA_InitStruct =
    {
        .periph_addr            = (unsigned int)0,            //外设地址
        .memory0_addr           = (unsigned int)0,            //存储器地址
        .direction              = DMA_PERIPH_TO_MEMORY,       //P->M
        .number                 = 0,                          //传输个数
        .circular_mode          = DMA_CIRCULAR_MODE_DISABLE,  //单次模式
        .periph_inc             = DMA_PERIPH_INCREASE_DISABLE,//外设地址不递增
        .memory_inc             = DMA_MEMORY_INCREASE_ENABLE, //存储器地址递增
        .periph_memory_width    = DMA_PERIPH_WIDTH_8BIT,      //外设数据大小为字节
        .priority               = DMA_PRIORITY_LOW,           //优先级最低
    };

    DMA_InitStruct.periph_addr = WHT_UART->Name + 0x04U;                //外设基地址
    DMA_InitStruct.memory0_addr = (unsigned int)WHT_UART->Cache->Rx_Buf;//存储器地址
    DMA_InitStruct.number = WHT_UART->Cache->Rx_Buf_Size;               //传输数据个数
    WHT_UART->DMA_Receive_Config.DMA_InitStruct = &DMA_InitStruct;

    WHT_UART->Info.Rx_State = UART_Rx_Idle;
    WHT_UART->Dma_Receive = ENABLE;
    WHT_UART->Cache->Rx_Count = 0;

    while (WHT_UART->DMA_Receive_Config.Info->BSP_Mutex == SET);//没有外设使用此通道的DMA
    WHT_UART->DMA_Receive_Config.Info->BSP_Mutex = SET;         //开启互斥锁
    WHT_DMA_BSP.WHT_Config(&WHT_UART->DMA_Receive_Config);      //配置当前DMA

    usart_interrupt_disable(WHT_UART->Name, USART_INT_RBNE);//接收寄存器非空
    usart_interrupt_enable(WHT_UART->Name, USART_INT_IDLE); //数据接收完成且总线空闲
    usart_dma_receive_config(WHT_UART->Name, USART_RECEIVE_DMA_ENABLE);//使能串口DMA接收请求
    usart_receive_config(WHT_UART->Name, USART_RECEIVE_ENABLE);//开启串口接收
}

/*全局常量*/
const WHT_UART_BSP_t WHT_UART_BSP =
{
    .WHT_Register          = WHT_UART_BSP_Register,
    .WHT_Config            = WHT_UART_BSP_Config,
    .WHT_Send              = WHT_UART_BSP_Send,
    .WHT_Interrupt_Send    = WHT_UART_BSP_Interrupt_Send,
    .WHT_DMA_Send          = WHT_UART_BSP_DMA_Send,
    .WHT_DMA_Receive       = WHT_UART_BSP_DMA_Receive,
    .WHT_Interrupt_Receive = WHT_UART_BSP_Interrupt_Receive,
};





/*串口中断发送回调函数*/
static void WHT_UART_BSP_IRQHandler_Send(const WHT_UART_Cache_t* cache, unsigned int* tx_count)
{
    if (usart_interrupt_flag_get(WHT_UART->Name, USART_INT_FLAG_TBE) == SET)//发送寄存器为空
    {
        if (*tx_count >= WHT_UART->Cache->Tx_Count)//是否数据发送完
        {
            usart_interrupt_disable(WHT_UART->Name, USART_INT_TBE);
            *tx_count = 0;
        }
        else
        {
            usart_data_transmit(WHT_UART->Name, WHT_UART->Cache->Tx_Buf[(*tx_count)++]);
        }
    }
    else if (usart_interrupt_flag_get(WHT_UART->Name, USART_INT_FLAG_TC) == SET)//发送完成且发送寄存器为空
    {
        usart_interrupt_disable(WHT_UART->Name, USART_INT_TC); //DMA发送有使用此串口中断，小心DMA未及时处理导致此中断发生
        usart_dma_transmit_config(WHT_UART->Name, USART_TRANSMIT_DMA_DISABLE);//关闭DMA请求
        WHT_UART->Info.Tx_State = UART_Tx_Idle;
        if (WHT_UART->Cache->Tx_Idle_IT_Callback != NULL)
            WHT_UART->Cache->Tx_Idle_IT_Callback();
    }
}
/*串口中断接收回调函数*/
static void WHT_UART_BSP_IRQHandler_Receive(const WHT_UART_Cache_t* cache)
{
    if (WHT_UART->Dma_Receive == DISABLE)
    {
        if (usart_interrupt_flag_get(WHT_UART->Name, USART_INT_FLAG_RBNE) == SET)//接收寄存器非空
        {
            if (WHT_UART->Cache->Rx_Count >= WHT_UART->Cache->Rx_Buf_Size)//接收数据个数是否超标
                usart_data_receive(WHT_UART->Name);  //丢弃接收到的数据
            else
            {
                WHT_UART->Cache->Rx_Buf[WHT_UART->Cache->Rx_Count] = usart_data_receive(WHT_UART->Name);
                WHT_UART->Cache->Rx_Count++;
                WHT_UART->Info.Rx_State = UART_Rx_Busy;
            }
        }
        else if (usart_interrupt_flag_get(WHT_UART->Name, USART_INT_FLAG_IDLE) == SET)//接收空闲
        {
            usart_receive_config(WHT_UART->Name, USART_RECEIVE_DISABLE);//关闭串口接收
            usart_data_receive(WHT_UART->Name);      //读取一下接收寄存器数据清除空闲标志位
            WHT_UART->Info.Rx_State = WHT_UART->Cache->Rx_Count >= WHT_UART->Cache->Rx_Buf_Size ? UART_Rx_Overflow : UART_Rx_Idle;//接收数据个数是否超标
            if (WHT_UART->Cache->Rx_Idle_IT_Callback != NULL)
                WHT_UART->Cache->Rx_Idle_IT_Callback();
        }
    }
    else
    {
        if (usart_interrupt_flag_get(WHT_UART->Name, USART_INT_FLAG_IDLE) == SET)//接收空闲
        {
            usart_receive_config(WHT_UART->Name, USART_RECEIVE_DISABLE);//关闭串口接收
            usart_dma_receive_config(WHT_UART->Name, USART_RECEIVE_DMA_DISABLE);//关闭串口DMA接收请求
            WHT_UART->Cache->Rx_Count = WHT_UART->Cache->Rx_Buf_Size - WHT_DMA_BSP.WHT_Get_Curr_Data_Count(&WHT_UART->DMA_Receive_Config);
            WHT_DMA_BSP.WHT_Close(&WHT_UART->DMA_Receive_Config);   //手动关闭DMA通道
            usart_data_receive(WHT_UART->Name);                     //在读取一次接收到的数据,用来清除空闲标志位
            usart_interrupt_disable(WHT_UART->Name, USART_INT_IDLE);//数据接收完成且总线空闲
            WHT_UART->Info.Rx_State = UART_Rx_Idle;
            if (WHT_UART->Cache->Rx_Idle_IT_Callback != NULL)
                WHT_UART->Cache->Rx_Idle_IT_Callback();
        }
    }
}

/*串口1中断服务程序*/
void USART0_IRQHandler(void)
{
    static unsigned int tx_count = 0;

    WHT_UART_BSP_IRQHandler_Send(WHT_UART1.Cache, &tx_count);
    WHT_UART_BSP_IRQHandler_Receive(WHT_UART1.Cache);
}
/*串口2中断服务程序*/
void USART1_IRQHandler(void)
{
    static unsigned int tx_count = 0;

    WHT_UART_BSP_IRQHandler_Send(WHT_UART2.Cache, &tx_count);
    WHT_UART_BSP_IRQHandler_Receive(WHT_UART2.Cache);
}
/*串口3中断服务程序*/
void USART2_IRQHandler(void)
{
    static unsigned int tx_count = 0;

    WHT_UART_BSP_IRQHandler_Send(WHT_UART3.Cache, &tx_count);
    WHT_UART_BSP_IRQHandler_Receive(WHT_UART3.Cache);
}
/*串口4中断服务程序*/
void UART3_IRQHandler(void)
{
    static unsigned int tx_count = 0;

    WHT_UART_BSP_IRQHandler_Send(WHT_UART4.Cache, &tx_count);
    WHT_UART_BSP_IRQHandler_Receive(WHT_UART4.Cache);
}
/*串口5中断服务程序*/
void UART4_IRQHandler(void)
{
    static unsigned int tx_count = 0;

    WHT_UART_BSP_IRQHandler_Send(WHT_UART5.Cache, &tx_count);
    WHT_UART_BSP_IRQHandler_Receive(WHT_UART5.Cache);
}
/*串口6中断服务程序*/
void USART5_IRQHandler(void)
{
    static unsigned int tx_count = 0;

    WHT_UART_BSP_IRQHandler_Send(WHT_UART6.Cache, &tx_count);
    WHT_UART_BSP_IRQHandler_Receive(WHT_UART6.Cache);
}
/*串口7中断服务程序*/
void UART6_IRQHandler(void)
{
    static unsigned int tx_count = 0;

    WHT_UART_BSP_IRQHandler_Send(WHT_UART7.Cache, &tx_count);
    WHT_UART_BSP_IRQHandler_Receive(WHT_UART7.Cache);
}
/*串口8中断服务程序*/
void UART7_IRQHandler(void)
{
    static unsigned int tx_count = 0;

    WHT_UART_BSP_IRQHandler_Send(WHT_UART8.Cache, &tx_count);
    WHT_UART_BSP_IRQHandler_Receive(WHT_UART8.Cache);
}
